Skip to content

Conversation

@i2h3
Copy link
Collaborator

@i2h3 i2h3 commented Nov 5, 2025

Originally, I set out to avoid the appearance of a system prompt of our app wanting to access data from other apps when it actually just tried to create a local socket file in its own group container for interprocess communication.

⚠️ Key Changes

  • Our app and its contained extensions now use an app group which complies with the conventional naming scheme. Instead of reusing the main bundle identifier as an app group identifier, the used app group identifier now has a prefix based on the development team. This is the option to have "unprovisioned" group containers at the cost of restricting compatibility to macOS and not being abled to use entitlements like keychain sharing. It simplifies the identity management and signing a lot in which we are also stuck with legacy hurdles impossible to overcome smoothly. See "Accessing app group containers in your existing macOS app" by Apple for further information.
  • The build settings of the NextcloudIntegration.xcodeproj were updated to use a new common base identifier based on Nextcloud instead of ownCloud. Also, redundant build settings around signing were removed.
  • Due to the use of the provisioned app group which requires a provisioning profile, automatically managed development signing had to be enabled for every target in the Xcode project to maintain the possibility to build.
  • Added app sandbox entitlement to the main app. The other relevant targets already had this as it is imposed on extensions as a requirement by the platform. This is an important step for the long term goal of enabling Mac App Store distribution. ✨ See "App Sandbox" by Apple for further information.
  • Added network client entitlement to the main app for obvious reasons.
  • Added entitlement for read-write access to files selected by users. This is required for features like the debug archive export which enables saving files outside the sandbox.
  • The socket files created for interprocess communication now are located within the sandboxed containers for the app. The previous location in the root of the container were still breaking the sandbox.
  • A container migration manifest was added which lets the macOS container service automatically migrate application data from legacy locations into the sandbox container specifically set up for it. See "Migrating your app’s files to its App Sandbox container" by Apple for further information.
  • Added Objective-C++ bridging code for security scoped URL handling because Qt does not take care of it. This is required to access files outside of the sandbox, in example when writing a ZIP archive during the debug archive export.
  • The file provider extension must place its logs and databases inside the new group container (group. prefix) so the main app can access it for creation of a debug archive. This renders the shared legacy account database migration code obsolete because it could not be accessed anyway.
  • The synchronization folder setup was changed to force the user to select the local target through a system dialog. This is necessary for the system to grant access to the location outside the sandbox.

☑️ To Do

A migration wizard might be necessary which requires the user to select every synchronization root folder once which set up in previous releases through an "open directory" panel by the system because that is how granting access permission to user-selected file system items work and required to persist access to those out of the sandbox.

😵 Caveats

Breaking File Provider Change

This is a breaking change for our file provider extension. Currently, I do not see a way to enable the app sandbox without setting up file provider domains for accounts from scratch. The compliance with the app sandbox requires to use a proper group container identifier and app sandbox migration manifests only support containers (not group containers), to my knowledge.

Should a 4.1 build look for the file provider extension data, it will look in the new group container initially and not find anything. This is equal to a complete reset.

UNIX Sockets

Long identifiers may break the UNIX socket-based IPC. The app sandbox makes long path prefixes inevitable. In example:

/Users/<redacted>/Library/Group Containers/NKUJUXUJ3B.com.nextcloud.desktopclient/Library/Application Support/.fileprovidersocket

It is about 122 characters long and there is a problem with that:

The issue is that the socket path is too long for QLocalServer on macOS. Unix domain sockets have a maximum path length of typically 104 characters, and your path exceeds this limit.

Apple XNU kernel source code for reference.

The solution for now is to keep it as short as possible but this may break with branded identifiers which are significantly longer than this reference case.

/Users/<redacted>/Library/Group Containers/NKUJUXUJ3B.com.nextcloud.desktopclient/fps

⚡️ Impact

This is not a simple bug fix but foundational changes to how security is implemented by our client on macOS. It requires extensive testing and cannot be delivered or ported back as a patch release. This is not just flipping a switch in some settings. The debug archive creation feature is an example how the technical debt of a missing app sandbox requires code refactoring.

🔗 Dependencies

This pull request requires these changes to NextcloudFileProviderKit.

@i2h3 i2h3 added this to the 4.1.0 milestone Nov 5, 2025
@i2h3 i2h3 requested a review from Copilot November 5, 2025 10:14
@i2h3 i2h3 self-assigned this Nov 5, 2025
@github-project-automation github-project-automation bot moved this to 🧭 Planning evaluation (don't pick) in 💻 Desktop Clients team Nov 5, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR migrates from using team-identifier-prefixed app groups to the standard group. prefix for macOS app group identifiers, and updates code signing configuration to use automatic signing with a specific development team.

  • Changed app group identifier format from $(TEAM_ID)$(BUNDLE_ID) to group.$(BUNDLE_ID)
  • Updated socket paths to use Library/Application Support/ subdirectories
  • Switched from manual to automatic code signing with NKUJUXUJ3B development team
  • Updated bundle identifiers from com.owncloud.* to com.nextcloud.*

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/gui/socketapi/socketapi_mac.mm Updated socket path to use group prefix and Application Support directory
src/gui/macOS/fileproviderutils_mac.mm Added whitespace formatting improvements
src/gui/macOS/fileprovidersocketserver_mac.mm Updated file provider socket path to use group prefix and Application Support directory
shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj Changed code signing from manual to automatic, updated development team ID, and changed bundle IDs from owncloud to nextcloud
shell_integration/MacOSX/NextcloudIntegration/FinderSyncExt/FinderSyncExt.entitlements Updated app group identifier to use group prefix
shell_integration/MacOSX/NextcloudIntegration/FinderSyncExt/FinderSync.m Updated socket path to use Application Support subdirectory
shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/FileProviderUIExt.entitlements Updated app group identifier to use group prefix
shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Info.plist Updated NCFPKAppGroupIdentifier to use group prefix
shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExt.entitlements Updated app group identifier to use group prefix
cmake/modules/MacOSXBundleInfo.plist.in Updated NCFPKAppGroupIdentifier template to use group prefix
admin/osx/macosx.entitlements.cmake Updated app group identifier template to use group prefix and added sandbox entitlements

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@i2h3 i2h3 force-pushed the i2h3/proper-macos-sandboxing branch from 38661b3 to a7f4af5 Compare November 5, 2025 12:51
@i2h3 i2h3 moved this from 🧭 Planning evaluation (don't pick) to 🏗️ In progress in 💻 Desktop Clients team Nov 5, 2025
@i2h3 i2h3 marked this pull request as ready for review November 5, 2025 13:47
@i2h3 i2h3 force-pushed the i2h3/proper-macos-sandboxing branch from 636553d to e37dada Compare November 5, 2025 14:03
@i2h3 i2h3 marked this pull request as draft November 5, 2025 14:13
@i2h3
Copy link
Collaborator Author

i2h3 commented Nov 5, 2025

I need to fix how the build settings are passed through now before it is ready for review.

@i2h3 i2h3 force-pushed the i2h3/proper-macos-sandboxing branch 2 times, most recently from 38055c2 to a78b990 Compare November 10, 2025 10:12
i2h3 added a commit to nextcloud/nextcloudfileproviderkit that referenced this pull request Nov 10, 2025
- These changes are related to making the main app bundle of the macOS build adopt the app sandbox entitlement which imposes certain restrictions on its file system access (nextcloud/desktop#9023).
- Logs are now written to the app group container because they are not accessible by the main app for creating debug archives otherwise.
- Databases are now written to the app group container because they are not accessible by the main app for creating debug archives otherwise.
- Removed legacy database migration code because it cannot work with the new app group identifier of the now sandboxed app anymore.
- Simplified database location assembly.

Signed-off-by: Iva Horn <[email protected]>
i2h3 added a commit to nextcloud/nextcloudfileproviderkit that referenced this pull request Nov 12, 2025
- These changes are related to making the main app bundle of the macOS build adopt the app sandbox entitlement which imposes certain restrictions on its file system access (nextcloud/desktop#9023).
- Logs are now written to the app group container because they are not accessible by the main app for creating debug archives otherwise.
- Databases are now written to the app group container because they are not accessible by the main app for creating debug archives otherwise.
- Removed legacy database migration code because it cannot work with the new app group identifier of the now sandboxed app anymore.
- Simplified database location assembly.

Signed-off-by: Iva Horn <[email protected]>
i2h3 added 8 commits November 12, 2025 10:58
- Removed redundant build settings about signing.
- Updated default base identifier from ownCloud to Nextcloud.

Signed-off-by: Iva Horn <[email protected]>
- Use automatically managed code signing.
- Defined Nextcloud GmbH (NKUJUXUJ3B) as the default development team.
- Set default code sign identity to "Apple Development".
- This is necessary because the new and correct group container identifier "group.com.nextcloud.desktopclient" requires a provisioning profile which requires development signing.

Signed-off-by: Iva Horn <[email protected]>
Content of sandboxed apps must not be created on the root level of a container but lower in the hierarchy of it.

Signed-off-by: Iva Horn <[email protected]>
…file.

- CODE_SIGN_IDENTITY
- CODE_SIGN_STYLE
- DEVELOPMENT_TEAM

Signed-off-by: Iva Horn <[email protected]>
i2h3 added 19 commits November 12, 2025 10:58
Also replaced the template file with a default file for build settings which can be overridden by environment variables.

Signed-off-by: Iva Horn <[email protected]>
- Replaced "group." with DEVELOPMENT_TEAM.
- Removed every occurrence of SOCKETAPI_TEAM_IDENTIFIER_PREFIX.
- Removed NCFPKAppGroupIdentifier from MacOSXBundleInfo.plist.in.

Signed-off-by: Iva Horn <[email protected]>
This is for working with a development branch of NextcloudFileProviderKit only while the required changes there have not been integrated yet. This reference must be removed in a follow up commit.

Signed-off-by: Iva Horn <[email protected]>
…topclient".

This was still missing in contrast to FileProviderExt. "desktopclient" is no the actual app for macOS but only a shallow wrapper and meta target to enable convenient build of everything in the Xcode project without building the main Qt app.

Signed-off-by: Iva Horn <[email protected]>
- Force an initial folder selection on folder wizard appearance.
- Turn the path text field into read only to force a change through the open folder dialog as required by the sandbox.
- On macOS, look up the actual user's home directory instead of the sandboxed container.
- Removed initial value for path text field in folder wizard because it was pointing into the sandbox container and also obsolete due to the forced folder selection on appearance.

Signed-off-by: Iva Horn <[email protected]>
@i2h3 i2h3 force-pushed the i2h3/proper-macos-sandboxing branch from 76982cb to 1534ff2 Compare November 12, 2025 09:58
@github-actions
Copy link

Artifact containing the AppImage: nextcloud-appimage-pr-9023.zip

Digest: sha256:95bdd35fc291800dba946cbbd19dae8fd91ccfe134f1305dd7a2709572fb8e64

To test this change/fix you can download the above artifact file, unzip it, and run it.

Please make sure to quit your existing Nextcloud app and backup your data.

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot
0.0% Coverage on New Code (required ≥ 80%)
55 New Code Smells (required ≤ 0)
B Maintainability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: 🏗️ In progress

Development

Successfully merging this pull request may close these issues.

2 participants